home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / viewers / prev / prev.lha / expr.c < prev    next >
C/C++ Source or Header  |  1991-01-29  |  5KB  |  306 lines

  1. #include <stdio.h>
  2. #include <math.h>
  3. #include "art.h"
  4.  
  5. float        eval_fexpr();
  6.  
  7. static    symbol    *vars = (symbol *)NULL;
  8.  
  9. /*
  10.  * defvar
  11.  *
  12.  *    define a variable
  13.  */
  14. defvar(s, e)
  15.     char        *s;
  16.     expression    *e;
  17. {
  18.     symbol        *var;
  19.  
  20.     var = insertsym(&vars, s);
  21.  
  22.     var->type = e->type;
  23.  
  24.     switch (e->type) {
  25.     case EXP_FLOAT:
  26.         var->u.f = e->u.f;
  27.         break;
  28.     case EXP_INT:
  29.         var->u.i = e->u.i;
  30.         break;
  31.     default:
  32.         fatal("art: bad expression in defvar.\n");
  33.     }
  34.  
  35.     free(e);
  36. }
  37.  
  38. /*
  39.  * get_varexpr
  40.  *
  41.  *    create an expression node for a variable.
  42.  */
  43. expression *
  44. get_varexpr(s)
  45.     char    *s;
  46. {
  47.     expression    *e;
  48.     symbol        *sym;
  49.     char        buf[BUFSIZ];
  50.  
  51.     e = (expression *)smalloc(sizeof(expression));
  52.  
  53.     if ((sym = findsym(vars, s)) == (symbol *)NULL) {
  54.         sprintf(buf, "art: variable %s not defined.\n", s);
  55.         fatal(buf);
  56.     }
  57.  
  58.     e->type = sym->type;
  59.  
  60.     switch (e->type) {
  61.     case EXP_FLOAT:
  62.         e->u.f = sym->u.f;
  63.         break;
  64.     case EXP_INT:
  65.         e->u.i = sym->u.i;
  66.         break;
  67.     default:
  68.         fatal("art: bad variable in get_varexpr.\n");
  69.     }
  70.  
  71.     return(e);
  72. }
  73.  
  74. /*
  75.  * get_ival
  76.  *
  77.  *    retrieve a symbol value returning an int.
  78.  */
  79. int
  80. get_ival(s)
  81.     char    *s;
  82. {
  83.     int    i;
  84.     symbol    *sym;
  85.     char    buf[BUFSIZ];
  86.  
  87.     sym = findsym(vars, s);
  88.  
  89.     if (sym == (symbol *)NULL) {
  90.         sprintf(buf, "art: symbol %s not defined.\n", s);
  91.         fatal(buf);
  92.     }
  93.  
  94.     if (sym->type == EXP_INT)
  95.         i = sym->u.i;
  96.     else if (sym->type == EXP_FLOAT)
  97.         i = sym->u.f;
  98.  
  99.     return(i);
  100. }
  101.  
  102. /*
  103.  * get_fval
  104.  *
  105.  *    retrieve a symbol value returning a float.
  106.  */
  107. float
  108. get_fval(s)
  109.     char    *s;
  110. {
  111.     float    f;
  112.     symbol    *sym;
  113.     char    buf[BUFSIZ];
  114.  
  115.     sym = findsym(vars, s);
  116.  
  117.     if (sym == (symbol *)NULL) {
  118.         sprintf(buf, "art: symbol %s not defined.\n", s);
  119.         fatal(buf);
  120.     }
  121.  
  122.     if (sym->type == EXP_INT)
  123.         f = sym->u.i;
  124.     else if (sym->type == EXP_FLOAT)
  125.         f = sym->u.f;
  126.  
  127.     return(f);
  128. }
  129.  
  130. /*
  131.  * get_type
  132.  *
  133.  *    work the return type for an expression
  134.  */
  135. int
  136. get_type(type, left, right)
  137.     int        type;
  138.     expression    *left, *right;
  139. {
  140.     if (right == (expression *)NULL)
  141.         return(left->type);
  142.  
  143.     if (left->type == EXP_FLOAT && right->type == EXP_FLOAT)
  144.         return(EXP_FLOAT);
  145.  
  146.     if (left->type == EXP_INT && right->type == EXP_INT)
  147.         return(EXP_INT);
  148.  
  149.     if (left->type == EXP_INT && right->type == EXP_FLOAT)
  150.         return(EXP_FLOAT);
  151.  
  152.     if (left->type == EXP_FLOAT && right->type == EXP_INT)
  153.         return(EXP_FLOAT);
  154.  
  155.     return(type);
  156. }
  157.  
  158. /*
  159.  * eval_fexpr
  160.  *
  161.  *    evaluate a floating point expression
  162.  */
  163. float 
  164. eval_fexpr(e)
  165.     expression    *e;
  166. {
  167.     float    f;
  168.  
  169.     switch (e->type) {
  170.     case EXP_INT:
  171.         f = e->u.i;
  172.         free(e);
  173.         break;
  174.     case EXP_FLOAT:
  175.         f = e->u.f;
  176.         free(e);
  177.         break;
  178.     default:
  179.         fatal("art: bad type in eval_fexpr.\n");
  180.     }
  181.  
  182.     return(f);
  183. }
  184.  
  185. /*
  186.  * eval_iexpr
  187.  *
  188.  *    evaluate an integer expression
  189.  */
  190. int
  191. eval_iexpr(e)
  192.     expression    *e;
  193. {
  194.     int    i;
  195.  
  196.     switch (e->type) {
  197.     case EXP_INT:
  198.         i = e->u.i;
  199.         free(e);
  200.         break;
  201.     case EXP_FLOAT:
  202.         i = e->u.f;
  203.         free(e);
  204.         break;
  205.     default:
  206.         fatal("art: bad type in eval_iexpr.\n");
  207.     }
  208.  
  209.     return(i);
  210. }
  211.  
  212. /*
  213.  * get_expr
  214.  *
  215.  *    get an expression node, compressing it if possible
  216.  */
  217. expression *
  218. get_expr(type, left, right)
  219.     int        type;
  220.     expression    *left, *right;
  221. {
  222.     int        ntype;
  223.     expression    *expr;
  224.  
  225.     ntype = get_type(type, left, right);
  226.  
  227.     expr = (expression *)smalloc(sizeof(expression));
  228.  
  229.     switch (type) {
  230.     case EXP_UMINUS:
  231.         switch (ntype) {
  232.         case EXP_FLOAT:
  233.             expr->type = EXP_FLOAT;
  234.             expr->u.f = -eval_fexpr(left);
  235.             break;
  236.         case EXP_INT:
  237.             expr->type = EXP_INT;
  238.             expr->u.i = -eval_iexpr(left);
  239.             break;
  240.         default:
  241.             fatal("art: bad subexpression type in get_expr.\n");
  242.         }
  243.         break;
  244.     case EXP_ADD:
  245.         switch (ntype) {
  246.         case EXP_FLOAT:
  247.             expr->type = EXP_FLOAT;
  248.             expr->u.f = eval_fexpr(left) + eval_fexpr(right);
  249.             break;
  250.         case EXP_INT:
  251.             expr->type = EXP_INT;
  252.             expr->u.i = eval_iexpr(left) + eval_iexpr(right);
  253.             break;
  254.         default:
  255.             fatal("art: bad subexpression type in get_expr.\n");
  256.         }
  257.         break;
  258.     case EXP_SUB:
  259.         switch (ntype) {
  260.         case EXP_FLOAT:
  261.             expr->type = EXP_FLOAT;
  262.             expr->u.f = eval_fexpr(left) - eval_fexpr(right);
  263.             break;
  264.         case EXP_INT:
  265.             expr->type = EXP_INT;
  266.             expr->u.i = eval_iexpr(left) - eval_iexpr(right);
  267.             break;
  268.         default:
  269.             fatal("art: bad subexpression type in get_expr.\n");
  270.         }
  271.         break;
  272.     case EXP_DIV:
  273.         switch (ntype) {
  274.         case EXP_FLOAT:
  275.             expr->type = EXP_FLOAT;
  276.             expr->u.f = eval_fexpr(left) / eval_fexpr(right);
  277.             break;
  278.         case EXP_INT:
  279.             expr->type = EXP_INT;
  280.             expr->u.i = eval_iexpr(left) / eval_iexpr(right);
  281.             break;
  282.         default:
  283.             fatal("art: bad subexpression type in get_expr.\n");
  284.         }
  285.         break;
  286.     case EXP_MUL:
  287.         switch (ntype) {
  288.         case EXP_FLOAT:
  289.             expr->type = EXP_FLOAT;
  290.             expr->u.f = eval_fexpr(left) * eval_fexpr(right);
  291.             break;
  292.         case EXP_INT:
  293.             expr->type = EXP_INT;
  294.             expr->u.i = eval_iexpr(left) * eval_iexpr(right);
  295.             break;
  296.         default:
  297.             fatal("art: bad subexpression type in get_expr.\n");
  298.         }
  299.         break;
  300.     default:
  301.         fatal("art: bad expression type in get_expr.\n");
  302.     }
  303.  
  304.     return(expr);
  305. }
  306.